
package com.joysuch.wwyt.dataperm;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.joysuch.wwyt.core.service.BaseRoleDataAuthService;
import com.joysuch.wwyt.dataperm.api.DataPermissionFilter;
import com.joysuch.wwyt.dataperm.context.DataPermContext;
import com.joysuch.wwyt.dataperm.context.DataPermContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

public class DataPermMvcInterceptor implements HandlerInterceptor {

    Logger logger = LoggerFactory.getLogger(DataPermMvcInterceptor.class);

    static final String DATA_PERM_SWITCH_ATTR = "wwyt.data_perm_switch_attr";
    static final String OPEN_DEV_LOG = "DATA_PERM_DEV_LOG";

    private DataPermissionFilter filter;

    private BaseRoleDataAuthService dataAuthService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        boolean shouldIntercept = lookupShouldIntercept(request);
        request.setAttribute(DATA_PERM_SWITCH_ATTR, shouldIntercept);
        processDevConfigs(request);
        logger.debug("拦截" + getRequestUriNoContextPath(request) + " => " + shouldIntercept);
        DataPermContextHolder.setDataPermTopSwitch(shouldIntercept);
        if (shouldIntercept) {
            DataPermContextHolder.setContext(createDataPermContext(request, handler));
        }
        return true;
    }

    private void processDevConfigs(HttpServletRequest request) {
        if (request.getParameter(OPEN_DEV_LOG) != null) {
            // 强制打开数据权限日志
            DataPermContextHolder.setPrintDevLog(true);
        }
    }

    private DataPermContext createDataPermContext(HttpServletRequest request, Object handler) {
        DataPermContext context = new DataPermContext();
        context.setUrl(getRequestUriNoContextPath(request));
        context.setEntryPoint(((HandlerMethod) handler).getMethod());
        context.setDeparts(findDataPermDeparts(request));
        return context;
    }

    private List<Long> findDataPermDeparts(HttpServletRequest request) {
        return dataAuthService.findDepartIdsByCurUser();
    }

    private boolean lookupShouldIntercept(HttpServletRequest request) {
        if (request.getParameter("MOCK_ROOT_DATA_PERM") != null) {
            // 模拟root用户，忽略所有数据权限过滤
            return false;
        }
        return filter.shouldFilter(getRequestUriNoContextPath(request));
    }

    private String getRequestUriNoContextPath(HttpServletRequest request) {
        String contextPath = request.getContextPath();
        if (contextPath.length() == 0 || contextPath.equals("/")) {
            return request.getRequestURI();
        }
        String uri = request.getRequestURI().substring(contextPath.length());
        if (!uri.startsWith("/")) {
            uri = "/" + uri;
        }

        return uri;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse arg1, Object handler, Exception arg3)
            throws Exception {
        // 清理本次请求的状态
        Boolean shouldIntercept = (Boolean) request.getAttribute(DATA_PERM_SWITCH_ATTR);
        DataPermContextHolder.clearContext();
        if (shouldIntercept) {
            DataPermContextHolder.clearContext();
        }
    }

    public DataPermissionFilter getFilter() {
        return filter;
    }

    public void setFilter(DataPermissionFilter filter) {
        this.filter = filter;
    }

    public void setDataAuthService(BaseRoleDataAuthService dataAuthService) {
        this.dataAuthService = dataAuthService;
    }
}
